#include "my_game.h"

lv_obj_t *block[HEIGHT_BOX_NUM][WIDE_BOX_NUM];
lv_obj_t *mainBackgroung;
lv_obj_t *RightBar;
Box my_box;
extern TaskMgr task_mgr;
extern lv_group_t *key_group; //键盘组

//围墙
LV_IMG_DECLARE(brick);
//基岩
LV_IMG_DECLARE(bedrock);
//人物(现在已经在settingPage中设置)
//LV_IMG_DECLARE(ps1);
//箱子
LV_IMG_DECLARE(chest);
//目的地
LV_IMG_DECLARE(enchanting_table_top);

static void task_wingame_judge(){
    int k = 0;
    for(int i = 0; i < HEIGHT_BOX_NUM; i++){
        for(int j = 0; j < WIDE_BOX_NUM; j++){
            if(my_box.current->map[i][j] == box){
                k++;
            }
        }
    }
    if (k == 0){
        lv_obj_t* m = lv_msgbox_create(mainBackgroung, NULL);
        lv_obj_t* label = lv_label_create(m,NULL);
        lv_obj_set_style_local_text_font(label, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT ,&mengTi);
        lv_label_set_text(label, "Congratulations!"); // 设置文本内容
        label = lv_label_create(m,NULL);
        lv_obj_set_style_local_text_font(label, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT ,&mengTi);
        lv_label_set_text(label, "Press reset to continue"); // 设置文本内容
        lv_obj_align(label, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 15);
    }
}
static void user_init_level(Level *p, int currentLevel)
{
    switch (currentLevel) {
        case 1: {
            for (int i = 0; i < HEIGHT_BOX_NUM; i++) {
                for (int j = 0; j < WIDE_BOX_NUM; j++) {
                    p->map[i][j] = map1[i][j];
                }
            }
            p->islocked = 0;
            p->pos_x = 4;//从0开始计数的
            p->pos_y = 6;
        } break;
        case 2: {
            for (int i = 0; i < HEIGHT_BOX_NUM; i++) {
                for (int j = 0; j < WIDE_BOX_NUM; j++) {
                    p->map[i][j] = map2[i][j];
                }
            }
            p->islocked = 1;
            p->pos_x = 4;
            p->pos_y = 6;
        } break;
        case 3: {
            for (int i = 0; i < HEIGHT_BOX_NUM; i++) {
                for (int j = 0; j < WIDE_BOX_NUM; j++) {
                    p->map[i][j] = map3[i][j];
                }
            }
            p->islocked = 1;
            p->pos_x = 4;
            p->pos_y = 6;
        } break;
        case 4: {
            for (int i = 0; i < HEIGHT_BOX_NUM; i++) {
                for (int j = 0; j < WIDE_BOX_NUM; j++) {
                    p->map[i][j] = map4[i][j];
                }
            }
            p->islocked = 1;
            p->pos_x = 4;
            p->pos_y = 8;
        } break;
        case 5: {
            for (int i = 0; i < HEIGHT_BOX_NUM; i++) {
                for (int j = 0; j < WIDE_BOX_NUM; j++) {
                    p->map[i][j] = map5[i][j];
                }
            }
            p->islocked = 1;
            p->pos_x = 4;
            p->pos_y = 6;
        } break;
        default:
            break;
    }
}

static void game_key_callback(struct _lv_obj_t *obj, lv_event_t event)
{

    if (event == LV_EVENT_KEY) {
        const uint32_t *key = lv_event_get_data();
        
        Level* p = my_box.current;
        UART_printf(&huart1, "\r\nevent = %d *key=%d", event, *key);
        if (*key == LV_KEY_UP) {
            if(p->map[p->pos_x - 1][p->pos_y] == null || p->map[p->pos_x - 1][p->pos_y] == aim){ //人的上方是空地或者目标位置
                p->map[p->pos_x][p->pos_y] -= 2;  //移动后，人的位置变成空地或者目标
                if(p->map[p->pos_x][p->pos_y] == null){
                        lv_img_set_src(block[p->pos_x][p->pos_y],&bedrock);
                    }
                else if(p->map[p->pos_x][p->pos_y] == aim){
                        lv_img_set_src(block[p->pos_x][p->pos_y],&enchanting_table_top);
                    }
                p->map[p->pos_x - 1][p->pos_y] += 2;//移动后,上方位置变成人或者人与目标结合
                lv_img_set_src(block[p->pos_x - 1][p->pos_y],choosedProfile(infoBox.chooseProfile));
                p->pos_x--;
            }
            else if(p->map[p->pos_x - 1][p->pos_y] == box || p->map[p->pos_x - 1][p->pos_y] == aim_with_box){ //人的上方是箱子或者是箱子和目的地重合
                if(p->map[p->pos_x - 2][p->pos_y] == null || p->map[p->pos_x - 2][p->pos_y] == aim ){ //箱子的上方是空地或者是终点
                    p->map[p->pos_x][p->pos_y] -= 2;  //移动后，人的位置变成空地或者目标
                    if(p->map[p->pos_x][p->pos_y] == null){
                        lv_img_set_src(block[p->pos_x][p->pos_y],&bedrock);
                    }
                    else if(p->map[p->pos_x][p->pos_y] == aim){
                        lv_img_set_src(block[p->pos_x][p->pos_y],&enchanting_table_top);
                    }
                    p->map[p->pos_x - 1][p->pos_y] -= 1;//移动后,上方位置变成人
                    lv_img_set_src(block[p->pos_x - 1][p->pos_y],choosedProfile(infoBox.chooseProfile));
                    p->map[p->pos_x - 2][p->pos_y] += 3;
                    lv_img_set_src(block[p->pos_x - 2][p->pos_y],&chest);
                    p->pos_x--;
                }
            }
            task_wingame_judge();
        } else if (*key == LV_KEY_DOWN) {
            if(p->map[p->pos_x + 1][p->pos_y] == null || p->map[p->pos_x + 1][p->pos_y] == aim){ //人的下方是空地或者目标位置
                p->map[p->pos_x][p->pos_y] -= 2;  //移动后，人的位置变成空地或者目标
                if(p->map[p->pos_x][p->pos_y] == null){
                        lv_img_set_src(block[p->pos_x][p->pos_y],&bedrock);
                    }
                else if(p->map[p->pos_x][p->pos_y] == aim){
                        lv_img_set_src(block[p->pos_x][p->pos_y],&enchanting_table_top);
                    }
                p->map[p->pos_x + 1][p->pos_y] += 2;//移动后,下方位置变成人或者人和目的地重合
                lv_img_set_src(block[p->pos_x + 1][p->pos_y],choosedProfile(infoBox.chooseProfile));
                p->pos_x++;
            }
            else if(p->map[p->pos_x + 1][p->pos_y] == box || p->map[p->pos_x + 1][p->pos_y] == aim_with_box){ //人的下方是箱子或者是箱子和目的地重合
                if(p->map[p->pos_x + 2][p->pos_y] == null || p->map[p->pos_x + 2][p->pos_y] == aim ){ //箱子的下方是空地或者是终点
                    p->map[p->pos_x][p->pos_y] -= 2;  //移动后，人的位置变成空地或者目标
                    if(p->map[p->pos_x][p->pos_y] == null){
                        lv_img_set_src(block[p->pos_x][p->pos_y],&bedrock);
                    }
                    else if(p->map[p->pos_x][p->pos_y] == aim){
                        lv_img_set_src(block[p->pos_x][p->pos_y],&enchanting_table_top);
                    }
                    p->map[p->pos_x + 1][p->pos_y] -= 1;
                    lv_img_set_src(block[p->pos_x + 1][p->pos_y],choosedProfile(infoBox.chooseProfile));
                    p->map[p->pos_x + 2][p->pos_y] += 3;
                    lv_img_set_src(block[p->pos_x + 2][p->pos_y],&chest);
                    p->pos_x++;
                }
            }
            task_wingame_judge();
        } else if (*key == LV_KEY_LEFT) {
            if(p->map[p->pos_x][p->pos_y - 1] == null || p->map[p->pos_x][p->pos_y - 1] == aim){ //人的左方是空地或者目标位置
                p->map[p->pos_x][p->pos_y] -= 2;  //移动后，人的位置变成空地或者目标
                if(p->map[p->pos_x][p->pos_y] == null){
                        lv_img_set_src(block[p->pos_x][p->pos_y],&bedrock);
                    }
                else if(p->map[p->pos_x][p->pos_y] == aim){
                        lv_img_set_src(block[p->pos_x][p->pos_y],&enchanting_table_top);
                    }
                p->map[p->pos_x][p->pos_y - 1] += 2;//移动后,左方位置变成人
                lv_img_set_src(block[p->pos_x][p->pos_y - 1],choosedProfile(infoBox.chooseProfile));
                p->pos_y--;
            }
            else if(p->map[p->pos_x][p->pos_y - 1] == box || p->map[p->pos_x][p->pos_y - 1] == aim_with_box){ //人的左方是箱子或者是箱子和目的地重合
                if(p->map[p->pos_x][p->pos_y - 2] == null || p->map[p->pos_x][p->pos_y - 2] == aim ){ //箱子的左方是空地或者是终点
                    p->map[p->pos_x][p->pos_y] -= 2;  //移动后，人的位置变成空地
                    if(p->map[p->pos_x][p->pos_y] == null){
                        lv_img_set_src(block[p->pos_x][p->pos_y],&bedrock);
                    }
                    else if(p->map[p->pos_x][p->pos_y] == aim){
                        lv_img_set_src(block[p->pos_x][p->pos_y],&enchanting_table_top);
                    }
                    p->map[p->pos_x][p->pos_y - 1] -= 1;
                    lv_img_set_src(block[p->pos_x][p->pos_y -1],choosedProfile(infoBox.chooseProfile));
                    p->map[p->pos_x][p->pos_y - 2] += 3;
                    lv_img_set_src(block[p->pos_x][p->pos_y -2],&chest);
                    p->pos_y--;
                }
            }
            task_wingame_judge();
        } else if (*key == LV_KEY_RIGHT) {
            if(p->map[p->pos_x][p->pos_y + 1] == null || p->map[p->pos_x][p->pos_y + 1] == aim){ //人的右方是空地或者目标位置
                p->map[p->pos_x][p->pos_y] -= 2;  //移动后，人的位置变成空地或者目标
                if(p->map[p->pos_x][p->pos_y] == null){
                        lv_img_set_src(block[p->pos_x][p->pos_y],&bedrock);
                    }
                else if(p->map[p->pos_x][p->pos_y] == aim){
                        lv_img_set_src(block[p->pos_x][p->pos_y],&enchanting_table_top);
                    }
                p->map[p->pos_x][p->pos_y+1] += 2;//移动后,右方位置变成人
                lv_img_set_src(block[p->pos_x][p->pos_y + 1],choosedProfile(infoBox.chooseProfile));
                p->pos_y++;
            }
            else if(p->map[p->pos_x][p->pos_y + 1] == box || p->map[p->pos_x][p->pos_y + 1] == aim_with_box){ //人的右方是箱子或者是箱子和目的地重合
                if(p->map[p->pos_x][p->pos_y + 2] == null || p->map[p->pos_x][p->pos_y + 2] == aim ){ //箱子的右方是空地或者是终点
                    p->map[p->pos_x][p->pos_y] -= 2;  //移动后，人的位置变成空地或者目标
                    if(p->map[p->pos_x][p->pos_y] == null){
                        lv_img_set_src(block[p->pos_x][p->pos_y],&bedrock);
                    }
                    else if(p->map[p->pos_x][p->pos_y] == aim){
                        lv_img_set_src(block[p->pos_x][p->pos_y],&enchanting_table_top);
                    }
                    p->map[p->pos_x][p->pos_y + 1] -= 1;
                    lv_img_set_src(block[p->pos_x][p->pos_y + 1],choosedProfile(infoBox.chooseProfile));
                    p->map[p->pos_x][p->pos_y + 2] += 3;
                    lv_img_set_src(block[p->pos_x][p->pos_y +2],&chest);
                    p->pos_y++;
                }
            }
            task_wingame_judge();
        } else if (*key == LV_KEY_ENTER) {
            task_mgr.Refresh_Game_request = 1;
        } else if (*key == LV_KEY_HOME) {
            task_mgr.Exit_Game_request = 1;
        }
    }
}

void mygame_init()
{
    my_box.head = NULL;
    my_box.tail = NULL;
    my_box.currentLevel = 1;
    for (int i = 0; i < 5; i++) { //暂定五个关卡
        Level *p = (Level *)malloc(sizeof(Level));
        //下面这段不要了，是否解锁由用户自定义
        // if (!i) {
        //     p->islocked = 1;
        // } else {
        //     p->islocked = 0;
        // }
        //初始化地图
        memset(p->map, 0, sizeof(p->map)); //初始化地图为0
        //读取地图信息
        //user_init_level(p,my_box.currentLevel);
        //loadMap_toSD(p, my_box.currentLevel);
        readMap_fromSD(p, my_box.currentLevel);
        Level *last = my_box.tail;
        if (last) { //确保last本身不是null，在只有一个头节点时
            my_box.tail->next = p;
            my_box.tail = p;
        } else { // last本身是null，说明这就是第一个，应该让head指向这一个
            my_box.head = p;
            my_box.tail = p;
        }
        // UART_printf(&huart1,"%d:%x,next:%x\n",my_box.currentLevel,p,p->next);
        my_box.currentLevel++;
    }
    my_box.currentLevel = 1;
}

int mygame_loadmap(Box *plist)
{
    Level *p = plist->head;
    int n = 1;
    while (n < plist->currentLevel) {
        p = p->next;
        n++;
    }
    my_box.current = p;
    /*此时p指向了level_num对应的关卡，接下来只需要对p对应的map操作就可以了*/
    mygame_maptest(p);
    return 1;
}

void mygame_maptest(Level *p)
{

    mainBackgroung = lv_obj_create(lv_scr_act(), NULL);
    lv_obj_set_style_local_radius(mainBackgroung, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, 0);
    lv_obj_set_style_local_bg_color(mainBackgroung, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLUE);
    lv_obj_set_pos(mainBackgroung, 0, 0);
    lv_obj_set_width(mainBackgroung, 800);
    lv_obj_set_height(mainBackgroung, 480);

    for (int i = 0; i < HEIGHT_BOX_NUM; i++) {
        for (int j = 0; j < WIDE_BOX_NUM; j++) {
            switch (p->map[i][j]) //(j,i)为屏幕上的坐标！！！！
            {
                case null: {
                    block[i][j] = lv_img_create(mainBackgroung, NULL);
                    lv_img_set_src(block[i][j], &bedrock);

                    lv_obj_set_pos(block[i][j], j * 60, i * 60);
                } break;
                case wall: {
                    block[i][j] = lv_img_create(mainBackgroung, NULL);
                    lv_img_set_src(block[i][j], &brick);
                    lv_obj_set_pos(block[i][j], j * 60, i * 60);
                } break;
                case person: {
                    block[i][j] = lv_img_create(mainBackgroung, NULL);
                    lv_img_set_src(block[i][j], choosedProfile(infoBox.chooseProfile));
                    lv_obj_set_pos(block[i][j], j * 60, i * 60);
                } break;
                case box: {
                    block[i][j] = lv_img_create(mainBackgroung, NULL);
                    lv_img_set_src(block[i][j], &chest);
                    lv_obj_set_pos(block[i][j], j * 60, i * 60);
                } break;
                case aim: {
                    block[i][j] = lv_img_create(mainBackgroung, NULL);
                    lv_img_set_src(block[i][j], &enchanting_table_top);
                    lv_obj_set_pos(block[i][j], j * 60, i * 60);
                } break;
                case aim_with_person:{
                    block[i][j] = lv_img_create(mainBackgroung, NULL);
                    lv_img_set_src(block[i][j], choosedProfile(infoBox.chooseProfile));
                    lv_obj_set_pos(block[i][j], j * 60, i * 60);
                } break;
                case aim_with_box:{
                    block[i][j] = lv_img_create(mainBackgroung, NULL);
                    lv_img_set_src(block[i][j], &chest);
                    lv_obj_set_pos(block[i][j], j * 60, i * 60);
                } break;
                default:
                    break;
            }
        }
    }
    RightBar = lv_btn_create(mainBackgroung, NULL);
    lv_obj_set_size(RightBar, 80, 480);
    lv_obj_set_pos(RightBar, 720, 0);

    //将图形按钮加入到组中
    lv_group_add_obj(key_group, RightBar);
    lv_obj_set_event_cb(RightBar, game_key_callback); //按钮的事件
    //图形的label
    lv_obj_t* btn_label1 = lv_label_create(RightBar,NULL);
    lv_obj_t* btn_label2 = lv_label_create(RightBar,NULL);
    lv_label_set_text(btn_label1, "Back->"); // 设置文本内容
    lv_obj_align(btn_label1, NULL, LV_ALIGN_OUT_TOP_MID, 0, 100);
    lv_label_set_text(btn_label2, "Reset->"); // 设置文本内容
    lv_obj_align(btn_label2, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 100);
    printf_Mem();
}
void delete_GamePage()
{
    lv_obj_del(mainBackgroung);
    //保存关卡数据
    Level *p = my_box.head;
    int n = 1;
    while (n < my_box.currentLevel) {
        p = p->next;
        n++;
    }
    loadMap_toSD(p, my_box.currentLevel);
}
void refresh_GamePage(){
    //删掉当前页面
    lv_obj_del(mainBackgroung);
    //从备份中加载数据
    Level *p = my_box.head;
    int n = 1;
    while (n < my_box.currentLevel) {
        p = p->next;
        n++;
    }
    user_init_level(p,my_box.currentLevel);
    //重载地图
    mygame_maptest(p);
    //保存数据（可无）
    loadMap_toSD(p, my_box.currentLevel);
}

